﻿using BCCommon;
using BCData.Common.WebsiteConfiguration;
using BCData.WeChatComponent.WeChatUserInfo;
using BCDto.WeChatComponent.WeChatUser;
using BCEntity.WeChatComponent.WeChatUserInfo;
using BCService.Utils;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WeChatSDK.WeChatServiceComponent.User;

namespace BCService.WeChatComponent.WeChatUserRelevantService
{
    /// <summary>
    /// 微信用户相关服务
    /// </summary>
    public class WeChatUserRelevantService : IWeChatUserRelevantService
    {
        private readonly IConfiguration configuration;
        private readonly IWeChatUserInfoData weChatUserInfoData;
        private readonly IWebsiteConfigurationData websiteConfigurationData;
        private readonly WeChatUserService weChatUserService = new WeChatUserService();
        private JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy { ProcessDictionaryKeys = false } },
            Converters = new List<JsonConverter> {
                new StringEnumConverter { AllowIntegerValues = true },
                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeLocal, DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }
            },
            NullValueHandling = NullValueHandling.Ignore
        };

        public WeChatUserRelevantService(IConfiguration configuration,IWeChatUserInfoData weChatUserInfoData,
            IWebsiteConfigurationData websiteConfigurationData)
        {
            this.configuration = configuration;
            this.weChatUserInfoData = weChatUserInfoData;
            this.websiteConfigurationData = websiteConfigurationData;
        }

        public void SynchronizeUserOpenId()
        {
            string nextOpenId = string.Empty;
            int count = 0;
            do
            {
                string response = this.GetUserList(nextOpenId);
                dynamic result = JsonConvert.DeserializeObject<dynamic>(response);
                count = result.count;
                nextOpenId = result.next_openid;
                string openIdStr = string.Join(",", result.data.openid);
                string[] openids = openIdStr.Split(',');
                this.weChatUserInfoData.AddOpenIds(openids);
            }
            while (count == 10000);
        }
        public void SynchronizeUserInfo()
        {
            int index = 0;
            bool exists = false;
            do
            {
                var openids = this.weChatUserInfoData.GetHundredUserOpenIds(index);
                exists = openids.Any();
                if (exists)
                {
                    WeChatUserListDto weChatUserListDto = this.BatchGetUserInfo(openids);
                    foreach (WeChatUserDto user in weChatUserListDto.UserInfoList)
                    {
                        this.weChatUserInfoData.Update(user.As<WeChatUserInfoEntity>());
                    }
                    index++;
                }
            }
            while (exists);
        }
        public WeChatUserListDto BatchGetUserInfo(IEnumerable<string> openIds, string lang = "zh_CN")
        {
            var response = WeChatHttpResponseHandle.ProcessMessage(this.weChatUserService.GetUserInfoByOpenIds(openIds.ToList(), lang));
            return JsonConvert.DeserializeObject<WeChatUserListDto>(response, jsonSerializerSettings);
        }

        public WeChatUserDto GetUserInfo(string openId, string lang = "zh_CN")
        {
            var response = WeChatHttpResponseHandle.ProcessMessage(this.weChatUserService.GetUserInfoByOpenId(openId, lang));
            return JsonConvert.DeserializeObject<WeChatUserDto>(response);
        }

        private string GetUserList(string nextOpenid)
        {
            return WeChatHttpResponseHandle.ProcessMessage(this.weChatUserService.GetUserOpenIdList(nextOpenid));
        }
        /// <summary>
        /// 微信用户根据临时Code登陆验证
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public WeChatUserDto Login(string code)
        {
            var response = WeChatHttpResponseHandle.ProcessMessage(this.weChatUserService.Login(code));
            return JsonConvert.DeserializeObject<WeChatUserDto>(response);
        }
        /// <summary>
        /// 微信用户根据临时Code登陆验证（小程序专用）
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public WeChatUserDto MinProgramLogin(string code)
        {
            var response = WeChatHttpResponseHandle.ProcessMessage(this.weChatUserService.MinProgramLogin(code));
            return JsonConvert.DeserializeObject<WeChatUserDto>(response);
        }
        public PageableList<WeChatUserInfoDto> Get(string name, DateTime? start, DateTime? end, int? tagId, string subscribeScene, string remark, string phone, string country, string province, string city, string role, bool? ascending, int pageIndex = 1, int pageSize = 10)
        {
            bool openUnionId = bool.Parse(configuration["WeChatService:OpenUnionId"]);
            var list = this.weChatUserInfoData.Get(openUnionId, name, start, end, tagId, subscribeScene, remark, phone, country, province, city, role, ascending, out int dataCount, pageIndex, pageSize);
           
            Parallel.ForEach(list, item =>
            {
                if (!string.IsNullOrWhiteSpace(item.Headimgurl))
                {
                    item.Headimgurl = item.Headimgurl.Replace("/132", "/46");
                }
            });
            return new PageableList<WeChatUserInfoDto>
            {
                Count = dataCount,
                Items = list.As<IEnumerable<WeChatUserInfoDto>>()
            };
        }

        public void UpdateRemark(string openid, string remark)
        {
            WeChatHttpResponseHandle.ProcessMessage(this.weChatUserService.UpdateUserNameRemark(openid, remark));
            WeChatUserInfoEntity entity = this.weChatUserInfoData.GetEntity(openid);
            if (entity == null)
            {
                WeChatUserDto user = this.GetUserInfo(openid);
                entity = user.As<WeChatUserInfoEntity>();
                this.weChatUserInfoData.Add(entity);
            }
            entity.Remark = remark;
            this.weChatUserInfoData.Update(entity);
        }
    }
}
